/*******************************************************************
 * Copyright (c) 2013 珠海比特讯科技有限公司. All rights reserved.
 * （1）软件的版权将受到法律保护，不允许非经授权的使用；
 * （2）未经版权所有人授权，任何人不得修改、复制和传播软件源代码、图片及其它资源等；
 * （3）未经版权所有人授权，不允许对软件进行修改；
 * （4）未经版权所有人授权，不允许在该软件的基础上开发新的软件；
 * （5）珠海比特讯科技有限公司拥有最终解释权
 *******************************************************************/
package youxiao.bytezon.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;

public class MapUtil {

	@SuppressWarnings("unchecked")
	public static Map<String, Object> toMap(Object obj) {
		ObjectMapper oMapper = new ObjectMapper();
		return oMapper.convertValue(obj, Map.class);
	}

	public static Map<String, Object> toMap(Object object, Set<String> fields) {
		Map<String, Object> map = objectToMap(object, fields);
		return map;
	}

	public static List<Map<String, Object>> toMapList(Set<?> objectList, Set<String> fields) {
		List<Map<String, Object>> mapList = Lists.newArrayList();
		for (Object object : objectList) {
			mapList.add(toMap(object, fields));
		}
		return mapList;
	}

	public static Object mapToObject(Map<String, Object> map, Class<?> beanClass) throws Exception {
		if (map == null || map.size() <= 0)
			return null;

		Object obj = beanClass.newInstance();

		BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(), Object.class);
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (PropertyDescriptor property : propertyDescriptors) {
			Method setter = property.getWriteMethod();
			if (setter != null) {
				setter.invoke(obj, map.get(property.getName()));
			}
		}

		return obj;
	}

	public static Map<String, Object> objectToMap(Object obj, Set<String> fields) {
		if (obj == null)
			return null;

		Map<String, Object> map = new HashMap<String, Object>();

		BeanInfo beanInfo;
		try {
			beanInfo = Introspector.getBeanInfo(obj.getClass(), Object.class);

			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				if (!fields.contains(key) || key.compareToIgnoreCase("class") == 0) {
					continue;
				}
				Method getter = property.getReadMethod();
				Object value = getter != null ? getter.invoke(obj) : null;
				map.put(key, value);
			}
		} catch (Exception e) {
			return null;
		}
		return map;
	}

}
